package cn.dancepeak.artcle.service.impl;

import cn.dancepeak.artcle.mapper.ArticleTypeMapper;
import cn.dancepeak.artcle.service.IArticleTypeServiceImpl;
import cn.dancepeak.exception.BusinessException;
import cn.dancepeak.article.domain.ArticleType;
import cn.dancepeak.article.query.ArticleTypeQuery;
import cn.dancepeak.vo.ArticleTypeTree;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@CacheConfig(cacheNames = "articleType")//全部都用同一个主key可以写在类上
public class ArticleTypeServiceImplImpl implements IArticleTypeServiceImpl {
    @Autowired
    private ArticleTypeMapper articleTypeMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    @CacheEvict(key = "'typeTree'")//去除缓存
    public void add(ArticleType articleType) {
        //密码新增以后要加密
        articleTypeMapper.insert(articleType);
    }

    @Override
    @CacheEvict(key = "'typeTree'")//去除缓存
    public void update(ArticleType articleType) {
        //用户名不能修改   禁用  在前端写
        articleTypeMapper.updateById(articleType);
    }

    @Override
    @CacheEvict(key = "'typeTree'")//去除缓存
    public void delete(Long id) {
        articleTypeMapper.deleteById(id);
    }

    @Override
    @CacheEvict(key = "'typeTree'")//去除缓存
    public void deleteByList(List<Long> ids) {
        articleTypeMapper.deleteByList(ids);
    }

    @Override
    public ArticleType getById(Long id) {
        return articleTypeMapper.selectById(id);
    }

    @Override
    public PageInfo<ArticleType> page(ArticleTypeQuery articleTypeQuery) {
        // 1.下面这句代码表示开启分页，会将紧挨着这句代码的下一次数据库执行进行分页，切记一定要放在要分页的SQL语句前面执行
        // 2.执行SQL语句带条件查询，SQL语句不需要进行分页
        PageHelper.startPage(articleTypeQuery.getCurrentPage(), articleTypeQuery.getPageSize());
        List<ArticleType> articleType = articleTypeMapper.list(articleTypeQuery);
        // 3.将查询结果转换为PageInfo对象，PageInfo对象中有前端分页所需要的各种参数
        PageInfo<ArticleType> pageInfo = new PageInfo<>(articleType);
        // 4.响应总条数和分页信息
        return pageInfo;
    }

    @Override
    @Cacheable(key = "'typeTree'")//添加缓存
    //无限极树
    public List<ArticleTypeTree> tree() {
        //1.查询出所有数据
        List<ArticleTypeTree> all = articleTypeMapper.listAll();
        //返回所有的顶级
        List<ArticleTypeTree> top = new ArrayList<>();
        //2.为了方便后续方便查找父亲，将集合对应转换成一个map
        Map<Long, ArticleTypeTree> map = all.stream().collect(Collectors.toMap(ArticleTypeTree::getId,type -> type));
        // 3.遍历所有数据
        for (ArticleTypeTree data : all) {
            // 3.1 找出parentId是是空的，就是顶级，返回给前端的集合
            if(data.getParentId() == null){
                top.add(data);
            }else  {
                // 3.2 parentId不是空，找自己的父亲，并将自己放入父亲的children中
                ArticleTypeTree parent = map.get(data.getParentId());
                parent.getChildren().add(data);
            }
        }
        return top;
    }

    @Override
    @CacheEvict(key = "'typeTree'")//去除缓存
    public void updateState(ArticleType articleType) {
        articleTypeMapper.updateState(articleType);
    }
}
